/*
 * Copyright (c) 2007 Compl Yue Still, All Rights Reserved.
 */

package hbi.wire.as3.host
{
	import flash.utils.IDataInput;
	import hbi.wire.ProtocolError;

	public class TypedArray implements DataTag
	{
		
		public function get tagValue():*
		{
			return content.tagValue;
		}
		
		public function reset():void
		{
			throw new Error("should never get called here.");
		}
		
		private var content:TypedArrayContent = null;
		
		private var dimension:int = 1;
		
		public function processIncomingData(input:IDataInput):Boolean
		{
			if(input.bytesAvailable < 1) return false;

			if(content == null) // type not read yet
			{
				tag_scan: while(input.bytesAvailable > 0)
				{
					var tag:int = input.readUnsignedByte();
					switch(tag)
					{
					case 'T'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new BoolElement());
						break;
					case 'I'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new Int32());
						break;
					case 'L'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new Int64());
						break;
					case 'D'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new FP64());
						break;
					case 'S'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new UTF8Chunks(true));
						break;
					case 'B'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new BinaryChunks(true));
						break;
					case 'd'.charCodeAt():
						content = new TypedArrayContent(dimension,
							new UTCDate());
						break;
					case '['.charCodeAt():
						dimension++;
						if(dimension > 127)
							throw new Error("Too deep array dimension!");
						continue tag_scan;
					case 's'.charCodeAt():
						throw new ProtocolError
							("Invalid array element type: Reader");
					case 'b'.charCodeAt():
						throw new ProtocolError
							("Invalid array element type: InputStream");
					default:
						throw new ProtocolError("Bad type tag: " + tag);
					}
					break tag_scan;
				}
			}

			if(input.bytesAvailable < 1) return false;

			if(content.processIncomingData(input))
				return true;

			return false;
		}
		
	}
}
